package com.fulihui.information.core.repository.impl;

import com.fulihui.information.core.repository.CategoryRepository;
import com.fulihui.information.dal.dataobj.InfoCategory;
import com.fulihui.information.dal.dataobj.InfoCategoryExample;
import com.fulihui.information.dal.mapper.InfoCategoryMapper;
import com.fulihui.information.dto.CategoryDTO;
import com.fulihui.information.enums.EYesOrNo;
import com.fulihui.information.request.CategorySaveRequest;
import com.fulihui.information.request.CategoryTransformSequenceRequest;
import org.near.servicesupport.error.Errors;
import org.near.servicesupport.error.InvokeServiceException;
import org.near.toolkit.common.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.support.TransactionTemplate;

import java.util.List;

import static com.fulihui.information.biz.conv.CategoryConv.*;
import static org.near.toolkit.common.StringUtil.isNotBlank;

/**
 * @author Willard.Hu on 2016/12/27 0027.
 */
@Repository
public class CategoryRepositoryImpl implements CategoryRepository {
    @Autowired
    private InfoCategoryMapper  infoCategoryMapper;
    @Autowired
    private TransactionTemplate transactionTemplate;

    /**
     * @see CategoryRepository#queryGroup(String, String)
     */
    @Override
    public List<CategoryDTO> queryGroup(String productCode, String parentCode) {
        InfoCategoryExample example = new InfoCategoryExample();
        InfoCategoryExample.Criteria criteria = example.createCriteria();
        criteria.andProductCodeEqualTo(productCode);
        if (StringUtil.isBlank(parentCode)) {
            criteria.andParentCodeIsNull();
        } else {
            criteria.andParentCodeEqualTo(parentCode);
        }
        criteria.andDisplayEqualTo(EYesOrNo.YES.getCode());
        example.setOrderByClause("sort_index");
        List<InfoCategory> list = infoCategoryMapper.selectByExample(example);
        return toList(list, true);
    }

    @Override
    public List<CategoryDTO> query(InfoCategoryExample example) {
        List<InfoCategory> list = infoCategoryMapper.selectByExample(example);
        return toList(list, false);
    }

    /**
     * @see CategoryRepository#insert(CategorySaveRequest)
     */
    @Override
    public void insert(CategorySaveRequest request) {
        InfoCategory record = toDataObj(request);
        InfoCategoryExample example = new InfoCategoryExample();
        InfoCategoryExample.Criteria criteria = example.createCriteria();
        criteria.andProductCodeEqualTo(request.getProductCode());
        if (isNotBlank(request.getParentCode())) {
            criteria.andParentCodeEqualTo(request.getParentCode());
        }
        record.setSortIndex((int) infoCategoryMapper.countByExample(example) + 1);
        infoCategoryMapper.insertSelective(record);
    }

    /**
     * @see CategoryRepository#update(CategorySaveRequest)
     */
    @Override
    public boolean update(CategorySaveRequest request) {
        InfoCategory record = toDataObj(request);
        return infoCategoryMapper.updateByPrimaryKeySelective(record) > 0;
    }

    /**
     * @see CategoryRepository#queryByCode(String)
     */
    @Override
    public CategoryDTO queryByCode(String code) {
        InfoCategory record = infoCategoryMapper.selectByPrimaryKey(code);
        return toDTO(record);
    }

    /**
     * @see CategoryRepository#transformSequence(CategoryTransformSequenceRequest)
     */
    @Override
    public boolean transformSequence(CategoryTransformSequenceRequest request) {
        return transactionTemplate.execute(status -> {
            InfoCategory record = new InfoCategory();
            record.setCode(request.getCodeA());
            record.setSortIndex(request.getSortIndexA());
            boolean b = infoCategoryMapper.updateByPrimaryKeySelective(record) > 0;

            InfoCategory record2 = new InfoCategory();
            record2.setCode(request.getCodeB());
            record2.setSortIndex(request.getSortIndexB());
            boolean b2 = infoCategoryMapper.updateByPrimaryKeySelective(record2) > 0;

            if (!b || !b2) {
                throw new InvokeServiceException(Errors.Commons.SYSTEM_ERROR);
            }
            return true;
        });
    }

}
